package model.compresion.LZP;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.Arrays;
import java.util.Random;



import model.archivo.ArchivoDiccionario;
import model.extras.FileExists;
import model.registro.ConversionesTiposDatos;
import junit.framework.TestCase;

public class TestLZPCompresion extends TestCase {

	/*
	public void testTablaLZP() throws FileNotFoundException, IOException{
		String Datos = new String("Bueno che, para evitar el futuro error de quedarnos sin memoria por crear muchas tablas de probabilidad al pedo cree un par de clases que se van a tener que usar cuando se quiera utilizar el aritmetico con un orden mayor a cer -RegistroPosicionFrecuencia: que tiene la posicion del caracter y la frecuencia -ListaFrecuencias: esta es una clase que implementa Iterable<RegistroPosicionFrecuencia> y que tiene una lista de RegistrosPosicionFrecuencia cuyo iterador se obtiene con el .iterator(), A la vez esta lista tiene un metodo aumentarFrecuencia(posicion) que aumenta la frecuencia del caracter del registro que esta en la lista que tenga el ID que se le pasa, si no lo encuentra crea dicho registro y le coloca 1 en su frecuencia. Este metodo lo que hace es aumentar la frecuancia en la catidad que sed le pase por parametro. Asi lo unico que hay que hacer para aumentar la frecuencia de un caracter es: Pero igualmente, tampoco entiendo bien como es que funciona la descompresion. Por lo que entiendo, leo 32 bits, lo convierto en un numero y se lo paso al modelo 0 de PPMC, emite ESC, bajo al modelo -1; y me fijo que numero es, que esta asociado a una letra, esa letra es es mi primer caracter.l pedo cree un par de clases que se van a tener que usar cuando se quiera utilizar el aritmetico con un orden mayor a cer -RegistroPosicionF... Luego le paso al descompresor aritmetico, la tabla de probabilidades, y el simbolo a descomprimir. El aritmetico calcula piso y techo, si hay overflow o underflow, modifica los 32 bits y me pasa los nuevos 32 bits, asi sucesivamente, y siempre que tengo un match, entonces emito la letra asociadaevitar el futuro error de quedarnos sin memoria por crear muchas tablas de probabilidad al pedo cree un par Suponiendo que voy a comprimir un archivo con PPMC, yo voy a guardar en un archivo en disco, todos los modelos que puede llegar a tener el compresor dependiendo el orden. Luego, sabiendo que cada modelo tiene diferentes contextos, voy a tiene una lista de contextos; donde cada elemento de la lista se identifica por un String que es el contexto mismo.Luego por cada contexto, yo voy a tener una lista de RegistrosSimbolos esta estructura, tienes un String para el simbolo del alfabeto unicode y un float para almacenar la probabilidadBueno che, para evitar el futuro error de quedarnos sin memoria por crear muchas tablas de probabilidad al pedo cree un par de clases que se van a tener que usar cuando se quiera utilizar el aritmetico con un o tar el futuro error de quedarnos sin memoria por crear muchas tablas de probabilidad al pedo cree un par de clases que se van a tener que usar cuando se quiera utilizar el aritmetico con un orden mayor a cer -RegistroPosicionFrecuencia: que tiene la posicion del caracter y la frecuencia -ListaFrecuencias: esta es una clase que implementa Iterable<RegistroPosicionFrecuencia> y que tiene una lista de RegistrosPosicionFrecuencia cuyo iterador se obtiene con el .iterator(), A la vez esta lista tiene un metodo aumentarFrecuencia(posicion) que aumenta la frecuencia del caracter del registro que esta en la lista que tenga el ID que se le pasa, si no lo encuentra crea dicho registro y le coloca 1 en su frecuencia. Este metodo lo que hace es aumentar la frecuancia en la catidad que sed le pase por parametro. Asi lo unico que hay que hacer para aumentar la frecuencia de un caracter es: Pero igualmente, tampoco entiendo bien como es que funciona la descompresion. Por lo que entiendo, leo 32 bits, lo convierto en un numero y se lo paso al modelo 0 de PPMC, emite ESC, bajo al modelo -1; y me fijo que numero es, que esta asociado a unLa idea del metodo compresor es que por cada caracter que me pasan para comprimir, me ubico en el modelo( orden) actual y abro el archivo asociado, luego en una estructura tipo lista, cargoLa primera supercomputadora, Cray-1 fue puesta en marcha en el Laboratorio Nacional de Los Álamos en 1976. La Cray-1 era capaz de operar a 80 MFLOPS. En poco más de treinta años desde entonces, la velocidad computacional de las supercomputadoras es más de un millón de veces mayor.La computadora más rápida del mundo hasta la fecha (12 Junio 2008) es la supercomputadora Roadrunner, capaz de un pico máximo de 1026 TeraFLOPS (más de 1 PetaFLOPS) con 12.960 procesadores Cell modificados (Play Station 3) y 6480 procesadores Opteron de AMD, que deben correr en paralelo para que la máquina funcione correctamente. Esta instalado en el Departamento Nacional de Seguridad Nuclear de Es todos los contextos de esa lista y voy comparando con mi contexto actuaa letra, esa letra es es mi primer caracter.l pedo cree un par de clases que se van a tener que usar cuando se ");
		byte[] bytesAComprimir= Datos.getBytes("UTF-16BE");		
		TablaLZP tabla = new TablaLZP();
		byte[][] compresion = tabla.comprimir(bytesAComprimir);
		byte[] descompresion = tabla.descomprimir(compresion[1], compresion[0]);
		String descString = new String(descompresion,"UTF-16BE");
		System.out.println(Datos);
		System.out.println(descString);
		System.out.println("Longitudes"+ compresion[0].length);
		for (int i = 0; i < compresion[0].length; i+=2) {
			System.out.print(ConversionesTiposDatos.BytesToShort(Arrays.copyOfRange(compresion[0], i, i+2))+" ");
		}
		System.out.println();
		System.out.println("Caracteres"+ compresion[1].length);
		String Aux = null;
		for (int i = 0; i < compresion[1].length; i+=2) {
			Aux = new String(Arrays.copyOfRange(compresion[1], i, i+2), "UTF-16BE");
			System.out.print(Aux);
		}
		System.out.println();
		System.out.println("Bytes 1º a comprimir 2º descomprimidos" + bytesAComprimir.length + " " + descompresion.length);
		for (int i = 0; i < bytesAComprimir.length; i+=2) {
			System.out.print(ConversionesTiposDatos.BytesToShort(Arrays.copyOfRange(bytesAComprimir, i, i+2))+" ");		
		}
		System.out.println();
		for (int i = 0; i < descompresion.length; i+=2) {
			System.out.print(ConversionesTiposDatos.BytesToShort(Arrays.copyOfRange(descompresion, i, i+2))+" ");
		}
	
	}*/
	
	/*public void testPersistencia(){
		Random random = new Random();
		byte[] bytes = new byte[3000];
		short aux = 0;
		for (int i = 0; i < bytes.length; i+=2) {
			aux = (short)random.nextInt(10000);
			if((i==20) || (i==22) || (i==24)||(i==26)||(i==28)||(i==30)||(i==32)){
				bytes[i] = ConversionesTiposDatos.ShortToBytes((short)3)[0];
				bytes[i+1] = ConversionesTiposDatos.ShortToBytes((short)3)[1];
			}
			else if ((i==2020) || (i==2022) || (i==2024)||(i==2026)||(i==2028)||(i==2030)||(i==2032)){
				bytes[i] = ConversionesTiposDatos.ShortToBytes((short)3)[0];
				bytes[i+1] = ConversionesTiposDatos.ShortToBytes((short)3)[1];
			}else{
				bytes[i] = ConversionesTiposDatos.ShortToBytes(aux)[0];
				bytes[i+1] = ConversionesTiposDatos.ShortToBytes(aux)[1];				
			}

			//System.out.print(i/2+") "+aux+" ");
		}
		System.out.println();

		try {
			TablaLZP tablaLPZ = new TablaLZP();
			//TablaLZP tablaLPZSinPers = new TablaLZP();
			tablaLPZ.comprimir(bytes);
			//tablaLPZSinPers.comprimirSinPersistencia(bytes);
			//System.out.println(tablaLPZ.toString());
			//System.out.println("SIN PERSISTENCIA:");
			//System.out.println(tablaLPZSinPers.toString());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}*/
	
	
	
	public void testCompresorTextoLZP() throws Exception{
		CompresorLZP compresor = new CompresorLZP();
		Random random = new Random();
		//String Datos = new String("esta es una clase que implementa Iterable<RegistroPosicionFrecuencia> y que tiene una lista de RegistrosPosicionFrecuencia cuyo iterador se obtiene con el .iterator(), A la vez esta lista tiene un metodo aumentarFrecuencia(posicion) que aumenta la frecuencia del caracter del registro que esta en l");		

		RandomAccessFile ArchivoEntrada = new RandomAccessFile("/home/alejandror/Desktop/e.txt","rw");
		if (ArchivoEntrada.getFilePointer()==ArchivoEntrada.length())
			return;
		byte[] DatosTemporal=new byte[(int)ArchivoEntrada.length()];
		for (int i=0; i<ArchivoEntrada.length(); i++)
			DatosTemporal[i]=ArchivoEntrada.readByte();
		ArchivoEntrada.close();

		String DatosEntrada = new String(DatosTemporal);
		byte[] bytesAComprimir=DatosEntrada.getBytes("UTF-16BE");
		
		byte[] compresion = compresor.comprimir(bytesAComprimir);
		
		
		RandomAccessFile ArchivoSalida = new RandomAccessFile("/home/alejandror/Desktop/e.txt.lzp","rw");
		for (int i=0; i<compresion.length; i++)
			ArchivoSalida.writeByte(compresion[i]);					
		ArchivoSalida.close();
		
		
		ArchivoEntrada = new RandomAccessFile("/home/alejandror/Desktop/e.txt.lzp","rw");
		if (ArchivoEntrada.getFilePointer()==ArchivoEntrada.length())
			return;
		byte[] DatosComprimidos=new byte[(int)ArchivoEntrada.length()];
		for (int i=0; i<ArchivoEntrada.length(); i++)
			DatosComprimidos[i]=ArchivoEntrada.readByte();
		ArchivoEntrada.close();
		
		
		byte[] descompresion = compresor.descomprimir(DatosComprimidos);
		System.out.println("La descompresion de la cadena es:");
		String desc = new String(descompresion,"UTF-16BE");
		System.out.println(desc);
		
		String DatosSalida = new String(descompresion, 0, descompresion.length, "UTF-16BE");
		
		ArchivoSalida = new RandomAccessFile("/home/alejandror/Desktop/eDesc.txt","rw");
		ArchivoSalida.write(DatosSalida.getBytes());
		ArchivoSalida.close();
		
/*		
		Writer output = null;
	    File file = new File("/home/alejandror/Desktop/eDesc.txt");
	    output = new BufferedWriter(new FileWriter(file));
	    output.write(desc.trim());
	    output.close();
	*/	
		
		/*
		File file = new File("/home/alejandror/Desktop/eDesc.txt");
		StringBuffer contents = new StringBuffer();
		BufferedReader reader = null;
		 
		try
		{
			reader = new BufferedReader(new FileReader(file));
			String text = null;
		 
			//		 repeat until all lines is read
			while ((text = reader.readLine()) != null)
				{
					contents.append(text).append(System.getProperty("line.separator"));
				}
		} catch (FileNotFoundException e){}
		if (reader != null)
		{
		reader.close();
		}
		*/
		
		
/*		byte[] bytesAComprimir= Datos.getBytes("UTF-16BE");		
		byte[] comprimido = compresor.compresionAritmeticaCaracter(bytesAComprimir);
		
		Datos = new String(compresor.descompresionAritmeticaCaracter(comprimido),"UTF-16BE");
		System.out.println(Datos);
		
		/*CompresorLZP compresor = new CompresorLZP();
		Random random = new Random();
		String Datos = new String("hola estoy en mi casa comiendo ravioles");		
*/
		//byte[] bytesAComprimir= Datos.getBytes("UTF-16BE");		
		
		
		
		
		/*
		TablaLZP tabla = new TablaLZP();
		byte[][] salidaLZP = tabla.comprimir(bytesAComprimir);
		System.out.println();
		byte[] compresion = compresor.comprimir(bytesAComprimir);
		byte[] descompresion = compresor.descomprimir(compresion);
		System.out.println("La descompresion de la cadena es:");
		String desc = new String(descompresion,"UTF-16BE");
		System.out.println(desc);
		for (int i = 0; i < descompresion.length; i+=2) {
			System.out.print(ConversionesTiposDatos.BytesToShort(Arrays.copyOfRange(descompresion, i, i+2))+" ");
		}
		System.out.println();
		System.out.println();
		System.out.println("Caracteres comprimidos por LZP antes y despues del aritmetico:");
		desc = new String(salidaLZP[1],"UTF-16BE");
		System.out.println(desc);
		for (int i = 0; i < salidaLZP[1].length; i+=2) {
			System.out.print(ConversionesTiposDatos.BytesToShort(Arrays.copyOfRange(salidaLZP[1], i, i+2))+" ");
		}
		System.out.println();
		int tamanioL = ConversionesTiposDatos.convertirBytesAInt(Arrays.copyOfRange(compresion, 0, 4));
		int tamanioC = ConversionesTiposDatos.convertirBytesAInt(Arrays.copyOfRange(compresion, tamanioL+4, tamanioL+8));
		CompresorLZP compresAux = new CompresorLZP();
		byte[] descompAritLong = compresAux.descompresionAritmeticaLongitud(Arrays.copyOfRange(compresion, 4, 4+tamanioL));
		System.out.println("entro a descomprimir car");
		byte[] descompAritCar = compresAux.descompresionAritmeticaCaracter(Arrays.copyOfRange(compresion, 8+tamanioL, 8+tamanioC+tamanioL));
		desc = new String(descompAritCar,"UTF-16BE");
		System.out.println(desc);
		for (int i = 0; i < descompAritCar.length; i+=2) {
			System.out.print(ConversionesTiposDatos.BytesToShort(Arrays.copyOfRange(descompAritCar, i, i+2))+" ");
		}
		System.out.println();
		System.out.println();
		System.out.println();
		System.out.println("Longitudes comprimidos por LZP antes y despues del aritmetico:");
		for (int i = 0; i < salidaLZP[0].length; i+=2) {
			System.out.print(ConversionesTiposDatos.BytesToShort(Arrays.copyOfRange(salidaLZP[0], i, i+2))+" ");
		}
		System.out.println();
		for (int i = 0; i < descompAritLong.length; i+=2) {
			System.out.print(ConversionesTiposDatos.BytesToShort(Arrays.copyOfRange(descompAritLong, i, i+2))+" ");
		}
		
		
		System.out.println();
		System.out.println("Descompresion LZP 1º antes del proceso 2º despues del proceso");
		
		for (int i = 0; i < bytesAComprimir.length; i++) {
			System.out.print(ConversionesTiposDatos.BytesToShort(Arrays.copyOfRange(bytesAComprimir, i, i+2))+" ");
		}
		System.out.println();
		for (int i = 0; i < descompresion.length; i++) {
			System.out.print(ConversionesTiposDatos.BytesToShort(Arrays.copyOfRange(descompresion, i, i+2))+" ");
		}
		System.out.println();

	}
	
	*/
	
	
	/*public void testCompresorNumerosLZP() throws Exception{
		CompresorLZP compresor = new CompresorLZP();
		Random random = new Random();	

		byte[] bytesAComprimir= new byte[50];
		short aux = 0;
		for (int i = 0; i < bytesAComprimir.length; i+=2) {
			aux = (short)random.nextInt(2);
			if((i==20) || (i==22) || (i==24)||(i==26)||(i==28)||(i==30)||(i==32)){
				bytesAComprimir[i] = ConversionesTiposDatos.ShortToBytes((short)3)[0];
				bytesAComprimir[i+1] = ConversionesTiposDatos.ShortToBytes((short)3)[1];
			}else if ((i==40) || (i==42) || (i==44)||(i==46)||(i==48)||(i==50)||(i==52)){
				bytesAComprimir[i] = ConversionesTiposDatos.ShortToBytes((short)3)[0];
				bytesAComprimir[i+1] = ConversionesTiposDatos.ShortToBytes((short)3)[1];
			}else if ((i==2020) || (i==2022) || (i==2024)||(i==2026)||(i==2028)||(i==2030)||(i==2032)){
				bytesAComprimir[i] = ConversionesTiposDatos.ShortToBytes((short)3)[0];
				bytesAComprimir[i+1] = ConversionesTiposDatos.ShortToBytes((short)3)[1];
			}else{
				bytesAComprimir[i] = ConversionesTiposDatos.ShortToBytes(aux)[0];
				bytesAComprimir[i+1] = ConversionesTiposDatos.ShortToBytes(aux)[1];				
			}

		}
		
		TablaLZP tabla = new TablaLZP();
		byte[][] salidaLZP = tabla.comprimir(bytesAComprimir);
		System.out.println();
		byte[] compresion = compresor.comprimir(bytesAComprimir);
		byte[] descompresion = compresor.descomprimir(compresion);
		String desc = new String(descompresion,"UTF-16BE");
		System.out.println(desc);
		for (int i = 0; i < salidaLZP[1].length; i++) {
			System.out.print(salidaLZP[1][i]+" ");
		}
		System.out.println();
		System.out.println("Longitudes");
		for (int i = 0; i < salidaLZP[0].length; i++) {
			System.out.print(salidaLZP[0][i]+" ");
		}
		System.out.println();
		System.out.println("Descompresion LZP 1º antes del proceso 2º despues del proceso");
		for (int i = 0; i < bytesAComprimir.length; i++) {
			System.out.print(bytesAComprimir[i]+" ");
		}
		System.out.println();
		for (int i = 0; i < descompresion.length; i++) {
			System.out.print(descompresion[i]+" ");
		}
		System.out.println();
*/
	}
	
/*	public void testCantTablasPosibles(){
		TablaProbabilidades[] tabla = new TablaProbabilidades[200];
		for (int i = 0; i < 100; i++) {
			tabla[i] = new TablaProbabilidades();
			System.out.println(i);
		}
	}*/
	/**
	 * @param args
	 * @throws UnsupportedEncodingException 
	 */
/*	public void testTablaLZP(){
		byte[] aComp = new byte[36];
		// TODO Auto-generated method stub
		aComp[0] = codificador.toBytes((short)3)[0];
		aComp[1] = codificador.toBytes((short)3)[1];
		aComp[2] = codificador.toBytes((short)4)[0];
		aComp[3] = codificador.toBytes((short)4)[1];
		aComp[4] = codificador.toBytes((short)3)[0];
		aComp[5] = codificador.toBytes((short)3)[1];
		aComp[6] = codificador.toBytes((short)4)[0];
		aComp[7] = codificador.toBytes((short)4)[1];
		aComp[8] = codificador.toBytes((short)3)[0];
		aComp[9] = codificador.toBytes((short)3)[1];
		aComp[10] = codificador.toBytes((short)4)[0];
		aComp[11] = codificador.toBytes((short)4)[1];
		aComp[12] = codificador.toBytes((short)3)[0];
		aComp[13] = codificador.toBytes((short)3)[1];
		aComp[14] = codificador.toBytes((short)4)[0];
		aComp[15] = codificador.toBytes((short)4)[1];
		aComp[16] = codificador.toBytes((short)4)[0];
		aComp[17] = codificador.toBytes((short)4)[1];
		aComp[18] = codificador.toBytes((short)4)[0];
		aComp[19] = codificador.toBytes((short)4)[1];
		aComp[20] = codificador.toBytes((short)4)[0];
		aComp[21] = codificador.toBytes((short)4)[1];
		aComp[22] = codificador.toBytes((short)3)[0];
		aComp[23] = codificador.toBytes((short)3)[1];
		aComp[24] = codificador.toBytes((short)4)[0];
		aComp[25] = codificador.toBytes((short)4)[1];
		aComp[26] = codificador.toBytes((short)3)[0];
		aComp[27] = codificador.toBytes((short)3)[1];
		aComp[28] = codificador.toBytes((short)4)[0];
		aComp[29] = codificador.toBytes((short)4)[1];
		aComp[30] = codificador.toBytes((short)4)[0];
		aComp[31] = codificador.toBytes((short)4)[1];
		aComp[32] = codificador.toBytes((short)4)[0];
		aComp[33] = codificador.toBytes((short)4)[1];
		aComp[34] = codificador.toBytes((short)65535)[0];
		aComp[35] = codificador.toBytes((short)65535)[1];
		TablaLZP tablaLPZ;
		try {
			tablaLPZ = new TablaLZP();
			tablaLPZ.comprimir(aComp);
			System.out.println(tablaLPZ.toString());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
*/
}
